import { env } from '@/shared/constants/env';
import { SelectProps } from '@/shared/interfaces';
import {
  CourseDto,
  CreationOrderDto,
  ListCourseAttachmentDto,
  ListCourseContentDto,
  ListCourseDto,
  ListOrderDto,
  ListQuestionDto,
  OrderCountPriceDto,
  OrderCountPriceResponseDto,
  OrderResponseDto,
  OrderV2Dto,
} from '@/shared/interfaces/generated';
import { RootState } from '@/shared/store';
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react';

export const productApi = createApi({
  reducerPath: 'productApi',
  tagTypes: ['Product', 'Order'],
  baseQuery: fetchBaseQuery({
    baseUrl: env.apiUrl,
    prepareHeaders: async (headers, query) => {
      const authResult = (query.getState() as RootState).auth;
      if (authResult && authResult.accessToken) {
        headers.set('authorization', `Bearer ${authResult.accessToken}`);
      }
      headers.set('Request-Source', 'site');
      return headers;
    },
    credentials: 'include',
  }),
  endpoints: (builder) => ({
    addProductToFavourites: builder.mutation<void, { userId?: number; productId?: number }>({
      query: ({ userId, productId }) => ({
        url: `/users/${userId}/favoriteProducts:add`,
        body: { productId },
        method: 'POST',
      }),
      invalidatesTags: ['Product'],
    }),
    deleteProductFromFavourites: builder.mutation<void, { userId?: number; productId?: number }>({
      query: ({ userId, productId }) => ({
        url: `/users/${userId}/favoriteProducts:remove`,
        body: { productId },
        method: 'POST',
      }),
      invalidatesTags: ['Product'],
    }),

    getSingleProduct: builder.query<CourseDto, string | number>({
      query: (id) => ({
        url: `/courses/${id}`,
      }),
      providesTags: ['Product'],
    }),
    getProducts: builder.query<
      ListCourseDto,
      {
        limit?: number;
        offset?: number;
        search?: string;
        'orderBy[order]'?: 'DESC' | 'ASC';
        'orderBy[price]'?: 'DESC' | 'ASC';
        'orderBy[publishedAt]'?: 'DESC' | 'ASC';
        'filters[topics]'?: string;
        'filters[formats]'?: string;
        'filters[companyId]'?: number;
        'filters[publicationStatusId]'?: number;
        'filters[companyPublicationStatusId]'?: number;
        'filters[favorite]'?: boolean;
        /** @example "2023-02-02" */
        'filters[maxPublishedAt]'?: string;
        /** @example "2023-02-02" */
        'filters[minPublishedAt]'?: string;
      }
    >({
      query: (params) => ({
        url: '/courses',
        params: { ...params, 'filters[publicationStatusId]': 3 },
      }),

      providesTags: ['Product'],
    }),
    getProductAttachments: builder.query<ListCourseAttachmentDto, string>({
      query: (id) => ({
        url: `/courses/${id}/attachments`,
      }),
      providesTags: ['Product'],
    }),
    getSingleProductAttachment: builder.query<ListCourseAttachmentDto, { courseId: string; attachmentId: string }>({
      query: ({ courseId, attachmentId }) => ({
        url: `/courses/${courseId}/attachments/${attachmentId}`,
      }),
      providesTags: ['Product'],
    }),
    getSingleProductContents: builder.query<ListCourseContentDto, string | number>({
      query: (id) => ({
        url: `/courses/${id}/contents`,
      }),
      providesTags: ['Product'],
    }),
    getSingleProductQuestions: builder.query<ListQuestionDto, string | number>({
      query: (id) => ({
        url: `/products/${id}/questions`,
      }),
      providesTags: ['Product'],
    }),

    getOrders: builder.query<
      ListOrderDto,
      {
        limit?: number;
        offset?: number;
        search?: string;
        'filters[requestSources]'?: string;
        'filters[userId]'?: number;
        'filters[statusId]'?: 1 | 2;
        'orderBy[createdAt]'?: 'DESC' | 'ASC';
      }
    >({
      query: (params) => ({
        url: '/orders',
        params: { ...params, 'filters[statusId]': 2 },
      }),

      providesTags: ['Product'],
    }),
    getSingleOrder: builder.query<OrderV2Dto, string>({
      query: (id) => ({
        url: `/orders/${id}`,
      }),

      providesTags: ['Product', 'Order'],
    }),
    getOrderPrice: builder.mutation<OrderCountPriceResponseDto, OrderCountPriceDto>({
      query: (body) => ({
        url: '/orders:countPrice',
        method: 'POST',
        body,
      }),
      invalidatesTags: ['Order'],
    }),
    createOrder: builder.mutation<OrderResponseDto, CreationOrderDto>({
      query: (body) => ({
        url: '/orders',
        method: 'POST',
        body,
      }),
      invalidatesTags: (result) => (result ? [{ type: 'Product', id: result.userId }] : ['Product']),
    }),
    orderFreeProduct: builder.mutation<void, { orderId: number }>({
      query: ({ orderId }) => ({
        url: `/payment/order/${orderId}/pay`,
        method: 'POST',
      }),
      invalidatesTags: ['Product'],
    }),

    getTopics: builder.query<{ topics: SelectProps[] }, void>({
      query: () => ({
        url: '/topics',
      }),
    }),
    getFormats: builder.query<{ formats: SelectProps[] }, void>({
      query: () => ({
        url: '/course-formats',
      }),
    }),
  }),
});
